package com.service.serviceImpl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.common.apiresult.CommonResult;
import com.common.apiresult.ResultCode;
import com.common.constant.RedisConstant;
import com.common.domain.dto.MaintainDTO;
import com.common.domain.dto.MaintainQueryDTO;
import com.common.domain.vo.MainTainPageVO;
import com.common.domain.vo.MainTainVO;
import com.common.exception.BusinessException;
import com.common.utils.RedisUtil;
import com.common.utils.TimeUtil;
import com.service.serviceInterface.DormService;
import com.service.serviceInterface.MaintainService;
import com.service.serviceInterface.UserService;
import com.system.entity.Building;
import com.system.entity.Dorm;
import com.system.entity.Maintain;
import com.system.mapper.BuildingMapper;
import com.system.mapper.MaintainMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.sql.SQLException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
import java.util.stream.Collectors;

/**
 *
 */
@Service
public class MaintainServiceImpl extends ServiceImpl<MaintainMapper, Maintain>
        implements MaintainService {
    @Resource
    private MaintainMapper maintainMapper;
    @Resource
    private UserService userService;
    @Resource
    private DormService dormService;
    @Resource
    private BuildingMapper buildingMapper;
    @Resource
    private TimeUtil timeUtil;
    @Resource
    private RedisUtil redisUtil;

    @Override
    @Transactional(rollbackFor = SQLException.class)
    public CommonResult add(MaintainDTO dto, long userId) {
        Maintain maintain = new Maintain();
        String images = dto.getPictures().stream().collect(Collectors.joining(","));
        maintain.setDormId(dto.getDormId()).setContext(dto.getContext()).setPicture(images).setAddUserId(userId).setAddTime(LocalDateTime.now());
        return maintainMapper.insert(maintain) == 1 ? CommonResult.success() : CommonResult.failed();
    }

    @Override
    public CommonResult updateMainTain(MaintainDTO dto) {
        Maintain maintain = new Maintain();
        maintain.setId(dto.getId()).setDormId(dto.getDormId()).setContext(dto.getContext()).setPicture(dto.getPictures().toString());
        return maintainMapper.updateById(maintain) == 1 ? CommonResult.success() : CommonResult.failed();
    }

    @Override
    public CommonResult getData(MaintainQueryDTO dto, long userId) {
        IPage<Maintain> page = selectList(dto, userId);
        List<Maintain> list = page.getRecords();
        if (list.size() <= 0) {
            return CommonResult.failed(ResultCode.RETURNNULL);
        }
        List<MainTainVO> vos = new ArrayList<>();
        for (Maintain i : list) {
            MainTainVO maintainVO = new MainTainVO();
            BeanUtils.copyProperties(i, maintainVO);
            if (!Objects.isNull(i.getHandleWorkId()) && StringUtils.isNotBlank(String.valueOf(i.getHandleWorkId())) && i.getHandleWorkId() != 0) {
                maintainVO.setHandleWorkName(userService.getUserNameById(i.getHandleWorkId()));
            }
            if (Objects.isNull(i.getHandleTime()) && timeUtil.comparableNowTime(i.getHandleTime()) < 0) {
                maintainVO.setDeleteUpdate(false);
            } else {
                maintainVO.setDeleteUpdate(true);
            }
            vos.add(maintainVO);
        }
        MainTainPageVO pageVO = new MainTainPageVO();
        pageVO.setVo(vos).setTotal(page.getTotal());
        return CommonResult.success(pageVO);
    }

    /**
     * 获取维修单
     * 水电工
     *
     * @param dto
     * @return
     */
    @Override
    public CommonResult getMainTainsDataByPlumber(MaintainQueryDTO dto) {
        /**
         * 查询所有维修单
         */
        IPage<Maintain> page = selectList(dto, 0);
        List<Maintain> list = page.getRecords();
        if (list.size() <= 0) {
            return CommonResult.failed(ResultCode.RETURNNULL);
        }
        /**
         * 判断有无值  无则写入
         */
        if (!redisUtil.hasKey(RedisConstant.BUILD_LIST)) {
            List<Building> buildings = buildingMapper.selectList(null);
            redisUtil.setList(RedisConstant.BUILD_LIST, buildings, 604800);
        }
        if (!redisUtil.hasKey(RedisConstant.DORM_LIST)) {
            List<Dorm> dorms = dormService.list(null);
            redisUtil.setList(RedisConstant.DORM_LIST, dorms, 604800);
        }
        /**
         * 读取楼宇列表   读取宿舍列表
         */
        List builds = redisUtil.getList(RedisConstant.BUILD_LIST);
        List<Building> buildList = new ArrayList<>();
        builds.forEach(i -> {
            Building building = new Building();
            BeanUtils.copyProperties(i, building);
            buildList.add(building);
        });
        List dorms = redisUtil.getList(RedisConstant.DORM_LIST);
        List<Dorm> dormList = new ArrayList<>();
        dorms.forEach(j -> {
            Dorm dorm = new Dorm();
            BeanUtils.copyProperties(j, dorm);
            dormList.add(dorm);
        });
        /**
         * 返回前端处理
         */
        List<MainTainVO> vos = new ArrayList<>();
        for (Maintain i : list) {
            MainTainVO maintainVO = new MainTainVO();
            BeanUtils.copyProperties(i, maintainVO);
            if (StringUtils.isNotBlank(i.getDormId().toString())) {
                dormList.stream().filter(k -> k.getId().equals(i.getDormId())).forEach(k -> buildList.stream().filter(z -> z.getId().equals(k.getBuildingId())).map(z -> z.getName() + " " + k.getDormName()).forEach(maintainVO::setDormName));
            }
            if (StringUtils.isNotBlank(String.valueOf(i.getHandleWorkId())) && i.getHandleWorkId() != 0) {
                maintainVO.setHandleWorkName(userService.getUserNameById(i.getHandleWorkId())).setDeleteUpdate(false);
            } else {
                maintainVO.setDeleteUpdate(true);
            }
            vos.add(maintainVO);
        }
        MainTainPageVO pageVO = new MainTainPageVO();
        pageVO.setVo(vos).setTotal(page.getTotal());
        return CommonResult.success(pageVO);
    }


    public IPage<Maintain> selectList(MaintainQueryDTO dto, long userId) {
        String date1 = "";
        String date2 = "";
        SimpleDateFormat endlishFormat = new SimpleDateFormat("EEE MMM dd yyyy hh:mm:ss", Locale.ENGLISH);
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM", Locale.CHINA);
        if (dto.getDateRange() != null && dto.getDateRange().get(0) != null && dto.getDateRange().get(0) != "") {
            String formatDate1 = dto.getDateRange().get(0).replace("GMT", "").replaceAll("\\(.*\\)", "");
            try {
                date1 = dateFormat.format(endlishFormat.parse(formatDate1)) + "-01";
                log.error(date1);
            } catch (ParseException e) {
                throw new BusinessException(ResultCode.VALIDATE_FAILED);
            }
        }
        if (dto.getDateRange() != null && dto.getDateRange().get(1) != null && dto.getDateRange().get(1) != "") {
            String formDate2 = dto.getDateRange().get(1).replace("GMT", "").replaceAll("\\(.*\\)", "");
            try {
                date2 = dateFormat.format(endlishFormat.parse(formDate2)) + "-01";
                LocalDate date = LocalDate.parse(date2, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
                date2 = date.with(TemporalAdjusters.lastDayOfMonth()).toString();
            } catch (ParseException e) {
                throw new BusinessException(ResultCode.VALIDATE_FAILED);
            }
        }
        Page<Maintain> page = new Page<>(dto.getPageNum(), dto.getPageSize());
        return maintainMapper.selectPage(page, addCondition(dto, date1, date2, userId));
    }

    public LambdaQueryWrapper<Maintain> addCondition(MaintainQueryDTO dto, String date1, String date2, long userId) {
        LambdaQueryWrapper<Maintain> wrapper = new LambdaQueryWrapper<>();
        if (StringUtils.isNotBlank(dto.getDormId())) {
            wrapper.eq(Maintain::getDormId, dto.getDormId());
        }
        if (StringUtils.isNotBlank(dto.getContext())) {
            wrapper.like(Maintain::getContext, dto.getContext());
        }
        if (StringUtils.isNotBlank(date1) && StringUtils.isNotBlank(date2)) {
            wrapper.between(Maintain::getAddTime, date1, date2);
        }
        if (!Objects.isNull(userId) && userId != 0) {
            wrapper.eq(Maintain::getAddUserId, userId);
        }
        wrapper.orderByDesc(Maintain::getAddTime);
        return wrapper;
    }
}




